dependent_var <- "MEDHVAL"

predictors <- c("PCTBACHMOR", "NBELPOV100", "PCTVACANT", "PCTSINGLES")

summary_stats <- data %>%
  dplyr::select(all_of(c(dependent_var, predictors))) %>%
  summarise_all(list(Mean = mean, SD = sd), na.rm = TRUE) %>%
  pivot_longer(cols = everything(), names_to = "Variable", values_to = "Value") %>%
  separate(Variable, into = c("Variable", "Stat"), sep = "_") %>%
  pivot_wider(names_from = Stat, values_from = Value)



summary_stats$Variable <- recode(summary_stats$Variable,
  "MEDHVAL" = "Median House Value",
  "NBELPOV100" = "# Households Living in Poverty",
  "PCTBACHMOR" = "% of Individuals with Bachelor’s Degrees or Higher",
  "PCTVACANT" = "% of Vacant Houses",
  "PCTSINGLES" = "% of Single House Units"
)



summary_stats <- summary_stats %>%
  mutate(
    Mean = round(Mean, 2),
    SD = round(SD, 2)
  )

summary_stats <- summary_stats %>%
  arrange(Variable == "Median House Value")

predictor_rows <- which(summary_stats$Variable != "Median House Value")
dependent_rows <- which(summary_stats$Variable == "Median House Value")

# Determine the start and end rows for each group
start_pred <- min(predictor_rows)
end_pred   <- max(predictor_rows)
start_dep  <- min(dependent_rows)
end_dep    <- max(dependent_rows)

# Create the table using kable and add extra formatting
kable(summary_stats, caption = "Summary Statistics", 
      align = c("l", "l", "l"), booktabs = TRUE, escape = FALSE ) %>%
  add_header_above(c(" " = 1, "Statistics" = 2)) %>%
  kable_styling(full_width = FALSE) %>%
  group_rows("Predictors", start_pred, end_pred) %>%
  group_rows("Dependent Variable", start_dep, end_dep)%>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = TRUE)
Summary Statistics
Statistics
Variable Mean SD
Predictors
% of Individuals with Bachelor’s Degrees or Higher 16.08 17.77
# Households Living in Poverty 189.77 164.32
% of Vacant Houses 11.29 9.63
% of Single House Units 9.23 13.25
Dependent Variable
Median House Value 66287.73 60006.08
#check 0
columns_to_check <- c(dependent_var, predictors)

zero_counts <- sapply(data[columns_to_check], function(x) sum(x == 0, na.rm = TRUE))

zero_counts[zero_counts > 0]
## PCTBACHMOR NBELPOV100  PCTVACANT PCTSINGLES 
##        143         33        163        306
data <- data %>%
  mutate(
    LNMEDHVAL = log(MEDHVAL),
    LNPCTBACHMOR = log(1+PCTBACHMOR),
    LNNBELPOV100 = log(1+NBELPOV100),
    LNPCTVACANT = log(1+PCTVACANT),
    LNPCTSINGLES = log(1+PCTSINGLES)
  )
longer_version<- data %>%
  pivot_longer(cols = c("MEDHVAL", "PCTBACHMOR", "NBELPOV100", "PCTVACANT", "PCTSINGLES"),
               names_to = "Variable",
               values_to = "Value")

ggplot(longer_version,aes(x = Value)) +
  geom_histogram(aes(y = ..count..), fill = "black", alpha = 0.7) +  
  facet_wrap(~Variable, scales = "free", ncol = 3, labeller = as_labeller(c(
    "MEDHVAL" = "Median House Value",
    "PCTBACHMOR" = "% with Bachelor’s Degrees or Higher",
    "NBELPOV100" = "# Households Living in Poverty",
    "PCTVACANT" = "% of Vacant Houses",
    "PCTSINGLES" = "% of Single House Units"
  ))) +  
  labs(x = "Value", y = "Count", title = "Histograms of Dependent and Predictor Variables") +
  theme_light() +   
  theme(plot.subtitle = element_text(size = 9,face = "italic"),
        plot.title = element_text(size = 12, face = "bold"), 
        axis.text.x=element_text(size=6),
        axis.text.y=element_text(size=6), 
        axis.title=element_text(size=8))

# histograms of the transformed variables
longer_version2 <- data %>%
  pivot_longer(cols = c(LNMEDHVAL, LNPCTBACHMOR ,LNNBELPOV100,LNPCTVACANT, LNPCTSINGLES),
               names_to = "Variable",
               values_to = "Value")

ggplot(longer_version2,aes(x = Value)) +
  geom_histogram(aes(y = ..count..), fill = "red", alpha = 0.7) +  
  facet_wrap(~Variable, scales = "free", ncol = 3, labeller = as_labeller(c(
    "LNMEDHVAL" = "Log Median House Value",
    "LNPCTBACHMOR" = "Log % with Bachelor’s Degree",
    "LNNBELPOV100" = "Log # Households in Poverty",
    "LNPCTVACANT" = "Log % Vacant Houses",
    "LNPCTSINGLES" = "Log % Single House Units"
  ))) +  
  labs(x = "Value", y = "Count", title = "Histograms of Dependent and log transformed Predictor Variables") +
  theme_light() +   
  theme(plot.subtitle = element_text(size = 9,face = "italic"),
        plot.title = element_text(size = 12, face = "bold"), 
        axis.text.x=element_text(size=6),
        axis.text.y=element_text(size=6), 
        axis.title=element_text(size=8))

ggplot(shape) +
  geom_sf(aes(fill = LNMEDHVAL), color = "transparent") +
  scale_fill_gradientn(colors = c("#fff0f3", "#a4133c"), 
                       name = "LNMEDHVAL", 
                       na.value = "transparent") + 
  theme(legend.text = element_text(size = 9),
        legend.title = element_text(size = 10),
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        axis.text.y = element_blank(),
        axis.ticks.y = element_blank(),
        plot.subtitle = element_text(size = 9, face = "italic"),
        plot.title = element_text(size = 12, face = "bold"),
        panel.background = element_blank(),
        panel.border = element_rect(colour = "grey", fill = NA, size = 0.8)) +
  labs(title = "Log Transformed Median House Value")

shpe_longer<- shape %>%
  pivot_longer(cols = c("PCTVACANT", "PCTSINGLES", "PCTBACHMOR", "LNNBELPOV"),
               names_to = "Variable",
               values_to = "Value")
custom_titles <- c(
  PCTVACANT   = "Percent of Vacant Houses",
  PCTSINGLES  = "Percent of Single House Units",
  PCTBACHMOR  = "Percent of Bachelor's Degree or Higher",
  LNNBELPOV   = "Logged Transformed Poverty Rate"
)



plot_list <- lapply(unique(shpe_longer$Variable), function(var_name) {
  data_subset <- subset(shpe_longer, Variable == var_name)
  
  ggplot(data_subset) +
    geom_sf(aes(fill = Value), color = "transparent") +
    scale_fill_gradientn(
      colors = c("#fff0f3", "#a4133c"),
      name = var_name,
      na.value = "transparent"
    ) +
    labs(title = custom_titles[[var_name]]) +
    theme(
      legend.text = element_text(size = 8),
      legend.title = element_text(size = 10),
      legend.key.size = unit(0.3, "cm"),
      axis.text.x = element_blank(),
      axis.ticks.x = element_blank(),
      axis.text.y = element_blank(),
      axis.ticks.y = element_blank(),
      plot.subtitle = element_text(size = 9, face = "italic"),
      plot.title = element_text(size = 15, face = "bold"),
      panel.background = element_blank(),
      panel.border = element_rect(colour = "grey", fill = NA, size = 0.8)
    )
})

# Combine the plots into a grid (2 columns by 2 rows)
combined_plot <- (plot_list[[1]] + plot_list[[2]]) /
                 (plot_list[[3]] + plot_list[[4]])

combined_plot

fit <- lm(LNMEDHVAL ~ PCTVACANT + PCTSINGLES + PCTBACHMOR + LNNBELPOV100, data=data)
summary(fit)
## 
## Call:
## lm(formula = LNMEDHVAL ~ PCTVACANT + PCTSINGLES + PCTBACHMOR + 
##     LNNBELPOV100, data = data)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -2.25825 -0.20391  0.03822  0.21744  2.24347 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  11.1137661  0.0465330 238.836  < 2e-16 ***
## PCTVACANT    -0.0191569  0.0009779 -19.590  < 2e-16 ***
## PCTSINGLES    0.0029769  0.0007032   4.234 2.42e-05 ***
## PCTBACHMOR    0.0209098  0.0005432  38.494  < 2e-16 ***
## LNNBELPOV100 -0.0789054  0.0084569  -9.330  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.3665 on 1715 degrees of freedom
## Multiple R-squared:  0.6623, Adjusted R-squared:  0.6615 
## F-statistic: 840.9 on 4 and 1715 DF,  p-value: < 2.2e-16
anova_table <- anova(fit)
anova_table
## Analysis of Variance Table
## 
## Response: LNMEDHVAL
##                Df  Sum Sq Mean Sq  F value    Pr(>F)    
## PCTVACANT       1 180.392 180.392 1343.087 < 2.2e-16 ***
## PCTSINGLES      1  24.543  24.543  182.734 < 2.2e-16 ***
## PCTBACHMOR      1 235.118 235.118 1750.551 < 2.2e-16 ***
## LNNBELPOV100    1  11.692  11.692   87.054 < 2.2e-16 ***
## Residuals    1715 230.344   0.134                       
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
fitted_values <- fitted(fit)
residuals_values <- residuals(fit)
standardized_residuals <- rstandard(fit)

data <- data %>%
  mutate(
    Fitted = fitted_values,
    Residuals = residuals_values,
    Standardized_Residuals = standardized_residuals)
ggplot(data, aes(x = Fitted, y = Standardized_Residuals)) +
  geom_point(color = "black", size= 0.4) +    
  geom_hline(yintercept = 0, linetype = "dashed", color = "red") +  
  labs(
    title = "Scatter Plot of Standardized Residuals vs Fitted Values",
    x = "Predicted Values",
    y = "Standardized Residuals"
  ) +
  theme_minimal() +   
  theme(plot.subtitle = element_text(size = 9,face = "italic"),
        plot.title = element_text(size = 12, face = "bold"), 
        axis.text.x=element_text(size=6),
        axis.text.y=element_text(size=6), 
        axis.title=element_text(size=8))

ggplot(data, aes(x = Standardized_Residuals)) +
  geom_histogram(bins = 30, fill = "black") +
  labs(title = "Histogram of Standardized Residuals", 
       x = "Standardized Residuals", 
       y = "Frequency") +
  theme_minimal() +   
  theme(plot.subtitle = element_text(size = 9,face = "italic"),
        plot.title = element_text(size = 12, face = "bold"), 
        axis.text.x=element_text(size=6),
        axis.text.y=element_text(size=6), 
        axis.title=element_text(size=8))

longer<-data %>%
  pivot_longer(cols = c("PCTBACHMOR", "LNNBELPOV100", "PCTVACANT", "PCTSINGLES"),
               names_to = "Variable",
               values_to = "Value")

ggplot(longer,aes(x = Value, y = LNMEDHVAL)) +
  geom_point(color = "black", size= 0.4) +
  geom_smooth(method = "lm", color = "red", se = FALSE) + 
  facet_wrap(~ Variable, scales = "free", labeller = as_labeller(c(
    "PCTBACHMOR" = "% with Bachelor’s Degrees or Higher",
    "LNNBELPOV100" = "Logged Households Living in Poverty",
    "PCTVACANT" = "% of Vacant Houses",
    "PCTSINGLES" = "% of Single House Units"
  )))  +
  theme_light() +   
  theme(plot.subtitle = element_text(size = 9,face = "italic"),
        plot.title = element_text(size = 12, face = "bold"), 
        axis.text.x=element_text(size=6),
        axis.text.y=element_text(size=6), 
        axis.title=element_text(size=8)) +
  labs(title = "Scatter Plots of Dependent Variable vs. Predictors", 
       x = "Predictor Value", 
       y = "Log of Median House Value")

join<- data %>%
  dplyr::select(POLY_ID, Standardized_Residuals)

shape <- shape %>%
  left_join(join, by = c("POLY_ID" = "POLY_ID"))

ggplot(shape)+
  geom_sf(aes(fill = Standardized_Residuals), color = "transparent") +
  scale_fill_gradientn(colors = c("#fff0f3", "#a4133c"), 
                       name = "Std Residuals", 
                       na.value = "transparent") +  # Choose a color palette, invert direction if needed
  labs(title = "Choropleth Map of Standardized Residuals") +
  theme(legend.text = element_text(size = 9),
        legend.title = element_text(size = 10),
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        axis.text.y = element_blank(),
        axis.ticks.y = element_blank(),
        plot.subtitle = element_text(size = 9, face = "italic"),
        plot.title = element_text(size = 12, face = "bold"),
        panel.background = element_blank(),
        panel.border = element_rect(colour = "grey", fill = NA, size = 0.8))

custom_labels <- c(
  "% of Individuals with Bachelor’s Degrees or Higher" = "PCTBACHMOR",
  "% of Vacant Houses" = "PCTVACANT",
  "% of Single House Units" = "PCTSINGLES",
  "# Households Living in Poverty" = "LNNBELPOV100"
)

predictor_vars <- data[, c("PCTVACANT", "PCTSINGLES", "PCTBACHMOR", "LNNBELPOV100")]

cor_matrix <- cor(predictor_vars, use = "complete.obs", method = "pearson")

print(cor_matrix)
##               PCTVACANT PCTSINGLES PCTBACHMOR LNNBELPOV100
## PCTVACANT     1.0000000 -0.1513734 -0.2983580    0.2495470
## PCTSINGLES   -0.1513734  1.0000000  0.1975461   -0.2905159
## PCTBACHMOR   -0.2983580  0.1975461  1.0000000   -0.3197668
## LNNBELPOV100  0.2495470 -0.2905159 -0.3197668    1.0000000
rownames(cor_matrix) <- names(custom_labels)
colnames(cor_matrix) <- names(custom_labels)


ggcorrplot(cor_matrix, 
           method = "square",   
           type = "lower",      
           lab = TRUE,       
           lab_size = 3,      
           colors = c("#d73027", "white", "#1a9850"))+
    labs(title = "Correlation Matrix for all Predictor Variables") +
    theme(plot.subtitle = element_text(size = 9, face = "italic"),
        plot.title = element_text(size = 12, face = "bold"), 
        axis.text.x = element_text(size = 7),
        axis.text.y = element_text(size = 7), 
        axis.title = element_text(size = 8))

stepwise_model <-  stepAIC(fit, direction = "both")
## Start:  AIC=-3448.07
## LNMEDHVAL ~ PCTVACANT + PCTSINGLES + PCTBACHMOR + LNNBELPOV100
## 
##                Df Sum of Sq    RSS     AIC
## <none>                      230.34 -3448.1
## - PCTSINGLES    1     2.407 232.75 -3432.2
## - LNNBELPOV100  1    11.692 242.04 -3364.9
## - PCTVACANT     1    51.546 281.89 -3102.7
## - PCTBACHMOR    1   199.020 429.36 -2379.0
stepwise_model$anova
## Stepwise Model Path 
## Analysis of Deviance Table
## 
## Initial Model:
## LNMEDHVAL ~ PCTVACANT + PCTSINGLES + PCTBACHMOR + LNNBELPOV100
## 
## Final Model:
## LNMEDHVAL ~ PCTVACANT + PCTSINGLES + PCTBACHMOR + LNNBELPOV100
## 
## 
##   Step Df Deviance Resid. Df Resid. Dev       AIC
## 1                       1715   230.3435 -3448.073
lm <-  trainControl(method = "cv", number = 5)

cvlm_model <- train(LNMEDHVAL ~ PCTVACANT + PCTSINGLES + PCTBACHMOR + LNNBELPOV100, data=data, method = "lm", trControl = lm)

print(cvlm_model)
## Linear Regression 
## 
## 1720 samples
##    4 predictor
## 
## No pre-processing
## Resampling: Cross-Validated (5 fold) 
## Summary of sample sizes: 1376, 1376, 1376, 1376, 1376 
## Resampling results:
## 
##   RMSE       Rsquared   MAE      
##   0.3660421  0.6613995  0.2716767
## 
## Tuning parameter 'intercept' was held constant at a value of TRUE
cvlm_model_reduced = train(LNMEDHVAL ~ PCTVACANT + MEDHHINC, data = data, method = "lm", trControl = lm)

print(cvlm_model_reduced)
## Linear Regression 
## 
## 1720 samples
##    2 predictor
## 
## No pre-processing
## Resampling: Cross-Validated (5 fold) 
## Summary of sample sizes: 1376, 1376, 1376, 1376, 1376 
## Resampling results:
## 
##   RMSE       Rsquared   MAE      
##   0.4425935  0.5085411  0.3178188
## 
## Tuning parameter 'intercept' was held constant at a value of TRUE
LS0tCnRpdGxlOiAnVXNpbmcgT0xTIFJlZ3Jlc3Npb24gdG8gUHJlZGljdCBNZWRpYW4gSG91c2UgVmFsdWVzIGluIFBoaWxhZGVscGhpYScKYXV0aG9yOiAiWmhhbmNoYW8gWWFuZywgSGFveXUgWmh1LCBLYXZhbmEgUmFqdSIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6CiAgICB0aGVtZTogdW5pdGVkCiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQoKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoc2YpCmxpYnJhcnkodGlkeWNlbnN1cykKbGlicmFyeShrbml0cikgCmxpYnJhcnkoZ3QpIApsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkoa2FibGVFeHRyYSkKbGlicmFyeShncmlkRXh0cmEpCmxpYnJhcnkoZ2djb3JycGxvdCkKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkoTUFTUykKbGlicmFyeShjYXJldCkKYGBgCgpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgaW5jbHVkZT0gRkFMU0V9CiMgTG9hZCB0aGUgZGF0YQpkYXRhIDwtIHJlYWQuY3N2KCJkYXRhL1JlZ3Jlc3Npb25EYXRhLmNzdiIpCnNoYXBlIDwtIHN0X3JlYWQoImRhdGEvUmVncmVzc2lvbkRhdGEuc2hwIikKYGBgCgoKYGBge3Igc3VtbWFyeSBzdGF0cywgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KZGVwZW5kZW50X3ZhciA8LSAiTUVESFZBTCIKCnByZWRpY3RvcnMgPC0gYygiUENUQkFDSE1PUiIsICJOQkVMUE9WMTAwIiwgIlBDVFZBQ0FOVCIsICJQQ1RTSU5HTEVTIikKCnN1bW1hcnlfc3RhdHMgPC0gZGF0YSAlPiUKICBkcGx5cjo6c2VsZWN0KGFsbF9vZihjKGRlcGVuZGVudF92YXIsIHByZWRpY3RvcnMpKSkgJT4lCiAgc3VtbWFyaXNlX2FsbChsaXN0KE1lYW4gPSBtZWFuLCBTRCA9IHNkKSwgbmEucm0gPSBUUlVFKSAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IGV2ZXJ5dGhpbmcoKSwgbmFtZXNfdG8gPSAiVmFyaWFibGUiLCB2YWx1ZXNfdG8gPSAiVmFsdWUiKSAlPiUKICBzZXBhcmF0ZShWYXJpYWJsZSwgaW50byA9IGMoIlZhcmlhYmxlIiwgIlN0YXQiKSwgc2VwID0gIl8iKSAlPiUKICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gU3RhdCwgdmFsdWVzX2Zyb20gPSBWYWx1ZSkKCgoKc3VtbWFyeV9zdGF0cyRWYXJpYWJsZSA8LSByZWNvZGUoc3VtbWFyeV9zdGF0cyRWYXJpYWJsZSwKICAiTUVESFZBTCIgPSAiTWVkaWFuIEhvdXNlIFZhbHVlIiwKICAiTkJFTFBPVjEwMCIgPSAiIyBIb3VzZWhvbGRzIExpdmluZyBpbiBQb3ZlcnR5IiwKICAiUENUQkFDSE1PUiIgPSAiJSBvZiBJbmRpdmlkdWFscyB3aXRoIEJhY2hlbG9y4oCZcyBEZWdyZWVzIG9yIEhpZ2hlciIsCiAgIlBDVFZBQ0FOVCIgPSAiJSBvZiBWYWNhbnQgSG91c2VzIiwKICAiUENUU0lOR0xFUyIgPSAiJSBvZiBTaW5nbGUgSG91c2UgVW5pdHMiCikKCgoKc3VtbWFyeV9zdGF0cyA8LSBzdW1tYXJ5X3N0YXRzICU+JQogIG11dGF0ZSgKICAgIE1lYW4gPSByb3VuZChNZWFuLCAyKSwKICAgIFNEID0gcm91bmQoU0QsIDIpCiAgKQoKc3VtbWFyeV9zdGF0cyA8LSBzdW1tYXJ5X3N0YXRzICU+JQogIGFycmFuZ2UoVmFyaWFibGUgPT0gIk1lZGlhbiBIb3VzZSBWYWx1ZSIpCgpwcmVkaWN0b3Jfcm93cyA8LSB3aGljaChzdW1tYXJ5X3N0YXRzJFZhcmlhYmxlICE9ICJNZWRpYW4gSG91c2UgVmFsdWUiKQpkZXBlbmRlbnRfcm93cyA8LSB3aGljaChzdW1tYXJ5X3N0YXRzJFZhcmlhYmxlID09ICJNZWRpYW4gSG91c2UgVmFsdWUiKQoKIyBEZXRlcm1pbmUgdGhlIHN0YXJ0IGFuZCBlbmQgcm93cyBmb3IgZWFjaCBncm91cApzdGFydF9wcmVkIDwtIG1pbihwcmVkaWN0b3Jfcm93cykKZW5kX3ByZWQgICA8LSBtYXgocHJlZGljdG9yX3Jvd3MpCnN0YXJ0X2RlcCAgPC0gbWluKGRlcGVuZGVudF9yb3dzKQplbmRfZGVwICAgIDwtIG1heChkZXBlbmRlbnRfcm93cykKCiMgQ3JlYXRlIHRoZSB0YWJsZSB1c2luZyBrYWJsZSBhbmQgYWRkIGV4dHJhIGZvcm1hdHRpbmcKa2FibGUoc3VtbWFyeV9zdGF0cywgY2FwdGlvbiA9ICJTdW1tYXJ5IFN0YXRpc3RpY3MiLCAKICAgICAgYWxpZ24gPSBjKCJsIiwgImwiLCAibCIpLCBib29rdGFicyA9IFRSVUUsIGVzY2FwZSA9IEZBTFNFICkgJT4lCiAgYWRkX2hlYWRlcl9hYm92ZShjKCIgIiA9IDEsICJTdGF0aXN0aWNzIiA9IDIpKSAlPiUKICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBGQUxTRSkgJT4lCiAgZ3JvdXBfcm93cygiUHJlZGljdG9ycyIsIHN0YXJ0X3ByZWQsIGVuZF9wcmVkKSAlPiUKICBncm91cF9yb3dzKCJEZXBlbmRlbnQgVmFyaWFibGUiLCBzdGFydF9kZXAsIGVuZF9kZXApJT4lCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiLCAiY29uZGVuc2VkIiksIGZ1bGxfd2lkdGggPSBUUlVFKQoKYGBgCgoKCmBgYHtyfQojY2hlY2sgMApjb2x1bW5zX3RvX2NoZWNrIDwtIGMoZGVwZW5kZW50X3ZhciwgcHJlZGljdG9ycykKCnplcm9fY291bnRzIDwtIHNhcHBseShkYXRhW2NvbHVtbnNfdG9fY2hlY2tdLCBmdW5jdGlvbih4KSBzdW0oeCA9PSAwLCBuYS5ybSA9IFRSVUUpKQoKemVyb19jb3VudHNbemVyb19jb3VudHMgPiAwXQoKYGBgCgpgYGB7cn0KZGF0YSA8LSBkYXRhICU+JQogIG11dGF0ZSgKICAgIExOTUVESFZBTCA9IGxvZyhNRURIVkFMKSwKICAgIExOUENUQkFDSE1PUiA9IGxvZygxK1BDVEJBQ0hNT1IpLAogICAgTE5OQkVMUE9WMTAwID0gbG9nKDErTkJFTFBPVjEwMCksCiAgICBMTlBDVFZBQ0FOVCA9IGxvZygxK1BDVFZBQ0FOVCksCiAgICBMTlBDVFNJTkdMRVMgPSBsb2coMStQQ1RTSU5HTEVTKQogICkKYGBgCgpgYGB7ciwgZmlnLmhlaWdodD03LCBmaWcud2lkdGg9OSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KbG9uZ2VyX3ZlcnNpb248LSBkYXRhICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gYygiTUVESFZBTCIsICJQQ1RCQUNITU9SIiwgIk5CRUxQT1YxMDAiLCAiUENUVkFDQU5UIiwgIlBDVFNJTkdMRVMiKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiVmFyaWFibGUiLAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiVmFsdWUiKQoKZ2dwbG90KGxvbmdlcl92ZXJzaW9uLGFlcyh4ID0gVmFsdWUpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYWVzKHkgPSAuLmNvdW50Li4pLCBmaWxsID0gImJsYWNrIiwgYWxwaGEgPSAwLjcpICsgIAogIGZhY2V0X3dyYXAoflZhcmlhYmxlLCBzY2FsZXMgPSAiZnJlZSIsIG5jb2wgPSAzLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGMoCiAgICAiTUVESFZBTCIgPSAiTWVkaWFuIEhvdXNlIFZhbHVlIiwKICAgICJQQ1RCQUNITU9SIiA9ICIlIHdpdGggQmFjaGVsb3LigJlzIERlZ3JlZXMgb3IgSGlnaGVyIiwKICAgICJOQkVMUE9WMTAwIiA9ICIjIEhvdXNlaG9sZHMgTGl2aW5nIGluIFBvdmVydHkiLAogICAgIlBDVFZBQ0FOVCIgPSAiJSBvZiBWYWNhbnQgSG91c2VzIiwKICAgICJQQ1RTSU5HTEVTIiA9ICIlIG9mIFNpbmdsZSBIb3VzZSBVbml0cyIKICApKSkgKyAgCiAgbGFicyh4ID0gIlZhbHVlIiwgeSA9ICJDb3VudCIsIHRpdGxlID0gIkhpc3RvZ3JhbXMgb2YgRGVwZW5kZW50IGFuZCBQcmVkaWN0b3IgVmFyaWFibGVzIikgKwogIHRoZW1lX2xpZ2h0KCkgKyAgIAogIHRoZW1lKHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDksZmFjZSA9ICJpdGFsaWMiKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgZmFjZSA9ICJib2xkIiksIAogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPTYpLAogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPTYpLCAKICAgICAgICBheGlzLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTgpKQpgYGAKCgpgYGB7ciwgZmlnLmhlaWdodD03LCBmaWcud2lkdGg9OSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyBoaXN0b2dyYW1zIG9mIHRoZSB0cmFuc2Zvcm1lZCB2YXJpYWJsZXMKbG9uZ2VyX3ZlcnNpb24yIDwtIGRhdGEgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKExOTUVESFZBTCwgTE5QQ1RCQUNITU9SICxMTk5CRUxQT1YxMDAsTE5QQ1RWQUNBTlQsIExOUENUU0lOR0xFUyksCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gIlZhcmlhYmxlIiwKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gIlZhbHVlIikKCmdncGxvdChsb25nZXJfdmVyc2lvbjIsYWVzKHggPSBWYWx1ZSkpICsKICBnZW9tX2hpc3RvZ3JhbShhZXMoeSA9IC4uY291bnQuLiksIGZpbGwgPSAicmVkIiwgYWxwaGEgPSAwLjcpICsgIAogIGZhY2V0X3dyYXAoflZhcmlhYmxlLCBzY2FsZXMgPSAiZnJlZSIsIG5jb2wgPSAzLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGMoCiAgICAiTE5NRURIVkFMIiA9ICJMb2cgTWVkaWFuIEhvdXNlIFZhbHVlIiwKICAgICJMTlBDVEJBQ0hNT1IiID0gIkxvZyAlIHdpdGggQmFjaGVsb3LigJlzIERlZ3JlZSIsCiAgICAiTE5OQkVMUE9WMTAwIiA9ICJMb2cgIyBIb3VzZWhvbGRzIGluIFBvdmVydHkiLAogICAgIkxOUENUVkFDQU5UIiA9ICJMb2cgJSBWYWNhbnQgSG91c2VzIiwKICAgICJMTlBDVFNJTkdMRVMiID0gIkxvZyAlIFNpbmdsZSBIb3VzZSBVbml0cyIKICApKSkgKyAgCiAgbGFicyh4ID0gIlZhbHVlIiwgeSA9ICJDb3VudCIsIHRpdGxlID0gIkhpc3RvZ3JhbXMgb2YgRGVwZW5kZW50IGFuZCBsb2cgdHJhbnNmb3JtZWQgUHJlZGljdG9yIFZhcmlhYmxlcyIpICsKICB0aGVtZV9saWdodCgpICsgICAKICB0aGVtZShwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA5LGZhY2UgPSAiaXRhbGljIiksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGZhY2UgPSAiYm9sZCIpLCAKICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT02KSwKICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT02KSwgCiAgICAgICAgYXhpcy50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT04KSkKYGBgCgoKCgpgYGB7cixmaWcuaGVpZ2h0PTcsIGZpZy53aWR0aD05LHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmdncGxvdChzaGFwZSkgKwogIGdlb21fc2YoYWVzKGZpbGwgPSBMTk1FREhWQUwpLCBjb2xvciA9ICJ0cmFuc3BhcmVudCIpICsKICBzY2FsZV9maWxsX2dyYWRpZW50bihjb2xvcnMgPSBjKCIjZmZmMGYzIiwgIiNhNDEzM2MiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJMTk1FREhWQUwiLCAKICAgICAgICAgICAgICAgICAgICAgICBuYS52YWx1ZSA9ICJ0cmFuc3BhcmVudCIpICsgCiAgdGhlbWUobGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDkpLAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gOSwgZmFjZSA9ICJpdGFsaWMiKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImdyZXkiLCBmaWxsID0gTkEsIHNpemUgPSAwLjgpKSArCiAgbGFicyh0aXRsZSA9ICJMb2cgVHJhbnNmb3JtZWQgTWVkaWFuIEhvdXNlIFZhbHVlIikKYGBgCgoKYGBge3IsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xNSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0Kc2hwZV9sb25nZXI8LSBzaGFwZSAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IGMoIlBDVFZBQ0FOVCIsICJQQ1RTSU5HTEVTIiwgIlBDVEJBQ0hNT1IiLCAiTE5OQkVMUE9WIiksCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gIlZhcmlhYmxlIiwKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gIlZhbHVlIikKY3VzdG9tX3RpdGxlcyA8LSBjKAogIFBDVFZBQ0FOVCAgID0gIlBlcmNlbnQgb2YgVmFjYW50IEhvdXNlcyIsCiAgUENUU0lOR0xFUyAgPSAiUGVyY2VudCBvZiBTaW5nbGUgSG91c2UgVW5pdHMiLAogIFBDVEJBQ0hNT1IgID0gIlBlcmNlbnQgb2YgQmFjaGVsb3IncyBEZWdyZWUgb3IgSGlnaGVyIiwKICBMTk5CRUxQT1YgICA9ICJMb2dnZWQgVHJhbnNmb3JtZWQgUG92ZXJ0eSBSYXRlIgopCgoKCnBsb3RfbGlzdCA8LSBsYXBwbHkodW5pcXVlKHNocGVfbG9uZ2VyJFZhcmlhYmxlKSwgZnVuY3Rpb24odmFyX25hbWUpIHsKICBkYXRhX3N1YnNldCA8LSBzdWJzZXQoc2hwZV9sb25nZXIsIFZhcmlhYmxlID09IHZhcl9uYW1lKQogIAogIGdncGxvdChkYXRhX3N1YnNldCkgKwogICAgZ2VvbV9zZihhZXMoZmlsbCA9IFZhbHVlKSwgY29sb3IgPSAidHJhbnNwYXJlbnQiKSArCiAgICBzY2FsZV9maWxsX2dyYWRpZW50bigKICAgICAgY29sb3JzID0gYygiI2ZmZjBmMyIsICIjYTQxMzNjIiksCiAgICAgIG5hbWUgPSB2YXJfbmFtZSwKICAgICAgbmEudmFsdWUgPSAidHJhbnNwYXJlbnQiCiAgICApICsKICAgIGxhYnModGl0bGUgPSBjdXN0b21fdGl0bGVzW1t2YXJfbmFtZV1dKSArCiAgICB0aGVtZSgKICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLAogICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgICAgbGVnZW5kLmtleS5zaXplID0gdW5pdCgwLjMsICJjbSIpLAogICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA5LCBmYWNlID0gIml0YWxpYyIpLAogICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgZmFjZSA9ICJib2xkIiksCiAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiZ3JleSIsIGZpbGwgPSBOQSwgc2l6ZSA9IDAuOCkKICAgICkKfSkKCiMgQ29tYmluZSB0aGUgcGxvdHMgaW50byBhIGdyaWQgKDIgY29sdW1ucyBieSAyIHJvd3MpCmNvbWJpbmVkX3Bsb3QgPC0gKHBsb3RfbGlzdFtbMV1dICsgcGxvdF9saXN0W1syXV0pIC8KICAgICAgICAgICAgICAgICAocGxvdF9saXN0W1szXV0gKyBwbG90X2xpc3RbWzRdXSkKCmNvbWJpbmVkX3Bsb3QKYGBgCgoKYGBge3IgcmVncmVzc2lvbn0KZml0IDwtIGxtKExOTUVESFZBTCB+IFBDVFZBQ0FOVCArIFBDVFNJTkdMRVMgKyBQQ1RCQUNITU9SICsgTE5OQkVMUE9WMTAwLCBkYXRhPWRhdGEpCnN1bW1hcnkoZml0KQpgYGAKYGBge3J9CmFub3ZhX3RhYmxlIDwtIGFub3ZhKGZpdCkKYW5vdmFfdGFibGUKYGBgCmBgYHtyfQpmaXR0ZWRfdmFsdWVzIDwtIGZpdHRlZChmaXQpCnJlc2lkdWFsc192YWx1ZXMgPC0gcmVzaWR1YWxzKGZpdCkKc3RhbmRhcmRpemVkX3Jlc2lkdWFscyA8LSByc3RhbmRhcmQoZml0KQoKZGF0YSA8LSBkYXRhICU+JQogIG11dGF0ZSgKICAgIEZpdHRlZCA9IGZpdHRlZF92YWx1ZXMsCiAgICBSZXNpZHVhbHMgPSByZXNpZHVhbHNfdmFsdWVzLAogICAgU3RhbmRhcmRpemVkX1Jlc2lkdWFscyA9IHN0YW5kYXJkaXplZF9yZXNpZHVhbHMpCmBgYAoKCgpgYGB7cn0KZ2dwbG90KGRhdGEsIGFlcyh4ID0gRml0dGVkLCB5ID0gU3RhbmRhcmRpemVkX1Jlc2lkdWFscykpICsKICBnZW9tX3BvaW50KGNvbG9yID0gImJsYWNrIiwgc2l6ZT0gMC40KSArICAgIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gInJlZCIpICsgIAogIGxhYnMoCiAgICB0aXRsZSA9ICJTY2F0dGVyIFBsb3Qgb2YgU3RhbmRhcmRpemVkIFJlc2lkdWFscyB2cyBGaXR0ZWQgVmFsdWVzIiwKICAgIHggPSAiUHJlZGljdGVkIFZhbHVlcyIsCiAgICB5ID0gIlN0YW5kYXJkaXplZCBSZXNpZHVhbHMiCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpICsgICAKICB0aGVtZShwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA5LGZhY2UgPSAiaXRhbGljIiksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGZhY2UgPSAiYm9sZCIpLCAKICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT02KSwKICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT02KSwgCiAgICAgICAgYXhpcy50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT04KSkKYGBgCgpgYGB7cn0KZ2dwbG90KGRhdGEsIGFlcyh4ID0gU3RhbmRhcmRpemVkX1Jlc2lkdWFscykpICsKICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMzAsIGZpbGwgPSAiYmxhY2siKSArCiAgbGFicyh0aXRsZSA9ICJIaXN0b2dyYW0gb2YgU3RhbmRhcmRpemVkIFJlc2lkdWFscyIsIAogICAgICAgeCA9ICJTdGFuZGFyZGl6ZWQgUmVzaWR1YWxzIiwgCiAgICAgICB5ID0gIkZyZXF1ZW5jeSIpICsKICB0aGVtZV9taW5pbWFsKCkgKyAgIAogIHRoZW1lKHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDksZmFjZSA9ICJpdGFsaWMiKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgZmFjZSA9ICJib2xkIiksIAogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPTYpLAogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPTYpLCAKICAgICAgICBheGlzLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTgpKQpgYGAKCgoKYGBge3IgZmlnLmhlaWdodD03LCBmaWcud2lkdGg9OSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KbG9uZ2VyPC1kYXRhICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gYygiUENUQkFDSE1PUiIsICJMTk5CRUxQT1YxMDAiLCAiUENUVkFDQU5UIiwgIlBDVFNJTkdMRVMiKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiVmFyaWFibGUiLAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiVmFsdWUiKQoKZ2dwbG90KGxvbmdlcixhZXMoeCA9IFZhbHVlLCB5ID0gTE5NRURIVkFMKSkgKwogIGdlb21fcG9pbnQoY29sb3IgPSAiYmxhY2siLCBzaXplPSAwLjQpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBjb2xvciA9ICJyZWQiLCBzZSA9IEZBTFNFKSArIAogIGZhY2V0X3dyYXAofiBWYXJpYWJsZSwgc2NhbGVzID0gImZyZWUiLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGMoCiAgICAiUENUQkFDSE1PUiIgPSAiJSB3aXRoIEJhY2hlbG9y4oCZcyBEZWdyZWVzIG9yIEhpZ2hlciIsCiAgICAiTE5OQkVMUE9WMTAwIiA9ICJMb2dnZWQgSG91c2Vob2xkcyBMaXZpbmcgaW4gUG92ZXJ0eSIsCiAgICAiUENUVkFDQU5UIiA9ICIlIG9mIFZhY2FudCBIb3VzZXMiLAogICAgIlBDVFNJTkdMRVMiID0gIiUgb2YgU2luZ2xlIEhvdXNlIFVuaXRzIgogICkpKSAgKwogIHRoZW1lX2xpZ2h0KCkgKyAgIAogIHRoZW1lKHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDksZmFjZSA9ICJpdGFsaWMiKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgZmFjZSA9ICJib2xkIiksIAogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPTYpLAogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPTYpLCAKICAgICAgICBheGlzLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTgpKSArCiAgbGFicyh0aXRsZSA9ICJTY2F0dGVyIFBsb3RzIG9mIERlcGVuZGVudCBWYXJpYWJsZSB2cy4gUHJlZGljdG9ycyIsIAogICAgICAgeCA9ICJQcmVkaWN0b3IgVmFsdWUiLCAKICAgICAgIHkgPSAiTG9nIG9mIE1lZGlhbiBIb3VzZSBWYWx1ZSIpCmBgYAoKCgpgYGB7ciwgZmlnLmhlaWdodD03LCBmaWcud2lkdGg9OSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0Kam9pbjwtIGRhdGEgJT4lCiAgZHBseXI6OnNlbGVjdChQT0xZX0lELCBTdGFuZGFyZGl6ZWRfUmVzaWR1YWxzKQoKc2hhcGUgPC0gc2hhcGUgJT4lCiAgbGVmdF9qb2luKGpvaW4sIGJ5ID0gYygiUE9MWV9JRCIgPSAiUE9MWV9JRCIpKQoKZ2dwbG90KHNoYXBlKSsKICBnZW9tX3NmKGFlcyhmaWxsID0gU3RhbmRhcmRpemVkX1Jlc2lkdWFscyksIGNvbG9yID0gInRyYW5zcGFyZW50IikgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGNvbG9ycyA9IGMoIiNmZmYwZjMiLCAiI2E0MTMzYyIpLCAKICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gIlN0ZCBSZXNpZHVhbHMiLCAKICAgICAgICAgICAgICAgICAgICAgICBuYS52YWx1ZSA9ICJ0cmFuc3BhcmVudCIpICsgICMgQ2hvb3NlIGEgY29sb3IgcGFsZXR0ZSwgaW52ZXJ0IGRpcmVjdGlvbiBpZiBuZWVkZWQKICBsYWJzKHRpdGxlID0gIkNob3JvcGxldGggTWFwIG9mIFN0YW5kYXJkaXplZCBSZXNpZHVhbHMiKSArCiAgdGhlbWUobGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDkpLAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gOSwgZmFjZSA9ICJpdGFsaWMiKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImdyZXkiLCBmaWxsID0gTkEsIHNpemUgPSAwLjgpKQoKYGBgCgoKCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQoKY3VzdG9tX2xhYmVscyA8LSBjKAogICIlIG9mIEluZGl2aWR1YWxzIHdpdGggQmFjaGVsb3LigJlzIERlZ3JlZXMgb3IgSGlnaGVyIiA9ICJQQ1RCQUNITU9SIiwKICAiJSBvZiBWYWNhbnQgSG91c2VzIiA9ICJQQ1RWQUNBTlQiLAogICIlIG9mIFNpbmdsZSBIb3VzZSBVbml0cyIgPSAiUENUU0lOR0xFUyIsCiAgIiMgSG91c2Vob2xkcyBMaXZpbmcgaW4gUG92ZXJ0eSIgPSAiTE5OQkVMUE9WMTAwIgopCgpwcmVkaWN0b3JfdmFycyA8LSBkYXRhWywgYygiUENUVkFDQU5UIiwgIlBDVFNJTkdMRVMiLCAiUENUQkFDSE1PUiIsICJMTk5CRUxQT1YxMDAiKV0KCmNvcl9tYXRyaXggPC0gY29yKHByZWRpY3Rvcl92YXJzLCB1c2UgPSAiY29tcGxldGUub2JzIiwgbWV0aG9kID0gInBlYXJzb24iKQoKcHJpbnQoY29yX21hdHJpeCkKcm93bmFtZXMoY29yX21hdHJpeCkgPC0gbmFtZXMoY3VzdG9tX2xhYmVscykKY29sbmFtZXMoY29yX21hdHJpeCkgPC0gbmFtZXMoY3VzdG9tX2xhYmVscykKCgpnZ2NvcnJwbG90KGNvcl9tYXRyaXgsIAogICAgICAgICAgIG1ldGhvZCA9ICJzcXVhcmUiLCAgIAogICAgICAgICAgIHR5cGUgPSAibG93ZXIiLCAgICAgIAogICAgICAgICAgIGxhYiA9IFRSVUUsICAgICAgIAogICAgICAgICAgIGxhYl9zaXplID0gMywgICAgICAKICAgICAgICAgICBjb2xvcnMgPSBjKCIjZDczMDI3IiwgIndoaXRlIiwgIiMxYTk4NTAiKSkrCiAgICBsYWJzKHRpdGxlID0gIkNvcnJlbGF0aW9uIE1hdHJpeCBmb3IgYWxsIFByZWRpY3RvciBWYXJpYWJsZXMiKSArCiAgICB0aGVtZShwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA5LCBmYWNlID0gIml0YWxpYyIpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyLCBmYWNlID0gImJvbGQiKSwgCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDcpLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA3KSwgCiAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpCmBgYAoKCmBgYHtyfQpzdGVwd2lzZV9tb2RlbCA8LSAgc3RlcEFJQyhmaXQsIGRpcmVjdGlvbiA9ICJib3RoIikKc3RlcHdpc2VfbW9kZWwkYW5vdmEKYGBgCmBgYHtyIGNyb3NzIHZhbGlkYXRpb24sIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmcgPSBGQUxTRX0KCmxtIDwtICB0cmFpbkNvbnRyb2wobWV0aG9kID0gImN2IiwgbnVtYmVyID0gNSkKCmN2bG1fbW9kZWwgPC0gdHJhaW4oTE5NRURIVkFMIH4gUENUVkFDQU5UICsgUENUU0lOR0xFUyArIFBDVEJBQ0hNT1IgKyBMTk5CRUxQT1YxMDAsIGRhdGE9ZGF0YSwgbWV0aG9kID0gImxtIiwgdHJDb250cm9sID0gbG0pCgpwcmludChjdmxtX21vZGVsKQoKYGBgCgoKYGBge3IgcmVkdWNlIGN2IG1vZGVsLG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgpjdmxtX21vZGVsX3JlZHVjZWQgPSB0cmFpbihMTk1FREhWQUwgfiBQQ1RWQUNBTlQgKyBNRURISElOQywgZGF0YSA9IGRhdGEsIG1ldGhvZCA9ICJsbSIsIHRyQ29udHJvbCA9IGxtKQoKcHJpbnQoY3ZsbV9tb2RlbF9yZWR1Y2VkKQpgYGAK